import os;
import io;
import stdx;
import math
import numpy;
import random;
from PIL import Image, ImageDraw, ImageFont, ImageFilter;

def GetColor(color, background = [255, 255, 255, 255]):
	if len(color) <= 3 or len(background) < 3: return color;
	cls = numpy.array(background);
	if len(cls) == 3: cls = numpy.append(cls, 255);
	tmp = numpy.array(color);
	m = tmp[3] / 255.0;
	n = 1 - m;
	tmp = (tmp * m + cls * n)[0:3] + [0.5, 0.5, 0.5];
	if isinstance(color, tuple): return tuple(numpy.int32(tmp));
	return numpy.int32(tmp);

def LoadImage(path, background = [255, 255, 255, 255]):
	img = Image.open(path);
	cx = img.size[0];
	cy = img.size[1];
	ps = [];
	data = img.load();
	for i in range(cx):
		for j in range(cy):
			ps.append(getColor(data[i, j], background));
	return ps;

def SaveImage(path, pixs):
	cx = len(pixs);
	cy = len(pixs[0]);
	img = Image.new('RGB', (cx, cy), (255, 255, 255));
	data = img.load();
	for i in range(cx):
		for j in range(cy):
			tmp = pixs[i, j];
			if len(tmp) < 3: data[i, j] = (tmp[0], tmp[0], tmp[0]);
			else: data[i, j] = tuple(tmp);
	return img.save(path);

def GetGrayPixls(ps):
	res = [];
	for i in range(len(ps)):
		res.append(int(sum(ps[i]) / len(ps[i]) + 0.5) % 256);
	return res;

def GetBinaryPixls(ps):	   
	res = [];
	for i in range(len(ps)):
		c = int(sum(ps[i]) / len(ps[i]) + 0.5) % 256;
		if c < 127: res.append(0);
		else: res.append(1);
	return res;

class TextLogo:
	__font__ = None;
	@staticmethod
	def __get_font__():
		if TextLogo.__font__: return TextLogo.__font__;
		TextLogo.__font__ = ImageFont.truetype(os.environ['CPPWEB_INSTALL_HOME'] + "/product/res/font/logotext.ttf", 20);
		return TextLogo.__font__;
	def __init__(self, text, color = None, font = None, format = 'png'):
		if font == None: font = TextLogo.__get_font__();
		if color == None:
			color = [];
			for ch in text:
				color.append((random.randint(0, 200), random.randint(0, 200), random.randint(0, 200), 255));
		self._text = text;
		self._font = font;
		self._data = None;
		self._color = color;
		self._format = format;
	def draw(self, color = None, filter = None, offset = (0, 0), background = None):
		if background == None: background = (0, 0, 0, 0);
		sz = [0, 0];
		szmap = {};
		for ch in self._text:
			tmp = self._font.getsize(ch);
			sz[0] += tmp[0];
			sz[1] += tmp[1];
			szmap[ch] = tmp; 
		sz[1] = sz[1] // len(self._text);
		cx = sz[0] + 8;
		cy = sz[1] + 4;
		img = Image.new('RGBA', (cx, cy), background);
		g = ImageDraw.Draw(img, 'RGBA');
		x = (cx - sz[0]) / 2;
		y = (cy - sz[1]) / 2;
		i = 0;
		for ch in self._text:
			chsz = szmap[ch];
			dx = chsz[1] - sz[1];
			if ch >= 'a'and ch <= 'z' and ch not in 'jfhlkbd': y = y - chsz[1] / 12;
			elif dx: y = y - dx / 2;
			if color == None: g.text((x + offset[0], y + offset[1]), ch, self._color[i], font = self._font);
			else: g.text((x + offset[0], y + offset[1]), ch, color, font = self._font);
			y = (cy - sz[1]) / 2;
			x = x + chsz[0];
			i = i + 1;
		if filter: img = img.filter(filter);
		with io.BytesIO() as fd:
			img.save(fd, self._format);
			fd.seek(0);
			self._data = fd.read();
			img.close();
			fd.close();
		return self._data;
	def getText(self):
		return self._text;
	def getData(self):
		return self._data;
	def getFormat(self):
		return self._format;

class CheckCode(TextLogo):
	__font__ = None;
	@staticmethod
	def __get_font__():
		if CheckCode.__font__: return CheckCode.__font__;
		CheckCode.__font__ = ImageFont.truetype(os.environ['CPPWEB_INSTALL_HOME'] + "/product/res/font/checkcode.ttf", 16);
		return CheckCode.__font__;
	def __init__(self, text = None, count = None, format = 'png'):
		if count == None: count = random.randint(4, 5);
		if text == None:
			text = '';
			arr = '234567892345678923456789ABCDEFGHJKLMNPQRSTUVWXYZEFGHJKLMNPQRSabcdefghijkmnpqrstuvwxyz';
			for idx in [random.randint(0, len(arr) - 1) for i in range(count)]: text = text + arr[idx];
		TextLogo.__init__(self, text, None, CheckCode.__get_font__(), format);